package com.data.basic.chapter02;

import java.util.Arrays;
import java.util.HashMap;

/**
 * 二次封装的数组
 */
public class Array<E> {
    private E [] data;
    private int size;

    /**
     * 构造函数，传入
     */

    public Array(int capacity) {
        data  = (E[]) new Object[capacity];
        size=0;
    }
// 无参数的构造函数
    public Array() {
        this(10);
    }
// 根据数组生成新的数组
    public Array(E[] arr) {
        data = (E[]) new Object[arr.length];
        for (int i=0;i<arr.length;i++){
            data[i] = arr[i];
        }
        size = arr.length;

    }

    public int getSize() {
        return size;
    }

    public int getCapacity(){
        return data.length;
    }
//数组是否为空
    public boolean isEmpty() {
//        return size>0?false:true ;
        return size==0 ;
    }

    /**
     * 在数组后端添加一个元素
     * @param e
     */
    public void addLast(E e){
        this.add(size,e);

    }
    public void addFirst(E e){
        this.add(0,e);

    }

    /**
     * 指定位置添加元素
     * @param index
     * @param e
     */
    public void add(int index,E e){
        if (size==data.length){//数组扩容
            resize(data.length<<1);
        }
        judgeIndex(index);

        for (int i=size-1;i>=index;i--){
            data[i+1] = data[i];
        }
        data[index] = e;
        size++;
    }

    private E[] resize(int newCapacity) {
        /**
         * 扩容数组
         */
        data = Arrays.copyOf(data,newCapacity);
        return data;
    }

    /**
     * 获取数组元素
     * @param index
     * @return
     */
    public E  get(int index){
        judgeIndex(index);
        return data[index];
    }

    /**
     * 修改元素
     * @param index
     * @param e
     */
    public void  set(int index,E e ){
    judgeIndex(index);
         data[index]=e;
    }

    /**
     *  查看是否有
     * @param e
     * @return
     */
    public boolean contains(E e){
        for(int i=0;i<size;i++){
            if (data[i].equals(e)){
                return true;
            }
        }
        return false;
    }

    /**
     * 查找元素的下标
     * @param e
     * @return
     */
    public int find(E e){
    for(int i=0;i<size;i++){
        if (data[i].equals(e)){
            return i;
        }
    }
    return -1;
}

    public E getLast(){
        return get(size-1);
//        return data[size-1];  //size为0时会不合法
    }

    public E getFirst(){
        return data[0];
    }

    /**
     *  按照索引删除
     * @param index
     * @return
     */
    public E remove(int index){
        judgeIndex(index);
        E ret = data[index];
        for (int i=index+1;i<size;i++){
            data[i-1] = data[i];
        }
        // 引用置成null
        data[size-1]=null;
        size--;
//当数组的空间删除到够小的时候，那就减少数组的空间
        if (size<data.length>>2&&data.length!=1){
            resize(data.length>>1);
        }


       return ret;

    }

    public E removeFirst(){
        return remove(0);
    }
    public E removelast(){
        return remove(size-1);
    }

    // 判断数组下标
    private void judgeIndex(int index){
        if (index<0||index>size){
            throw new IllegalArgumentException("Get fail! index is outOfMemory");
        }
    }
    // 按照元素删除    只删除一个e
    public void removeElement(E e){
        int index = find(e);
        if (index!=-1){
            remove(index);
        }
}

    /**
     * 交换元素
     * @return
     */
    public void swap(int i,int j){
        if (i<0||i>=size||j<0||j>=size){
            throw new IllegalArgumentException("index is illegal");
    }
        E temp = data[i];
        data[i] = data[j];
        data[j] = temp;
}

    @Override
    public String toString() {
        StringBuffer res = new StringBuffer();
        res.append(String.format("Array:size = %d, capcity = %d\n",size,getCapacity()));
        res.append("[");
        for (int i=0;i<size;i++){
            if (i!=size){
                res.append(data[i]);
                res.append(",");
            }
        }
        res.append("]");
        return res.toString();
    }

}
